﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DataBase
{
    public class BlogAdapter
    {
        public bool ArticleCreateUpdate(long? articleID, string title, string subTitle, string text,
            string author, string tags, string photo, bool allowComments)
        {
            try
            {
                using (var context = new blogEntities())
                {
                    #region update article
                    if (articleID.HasValue) // UPDATE
                    {
                        var article = context.Articles.Include("Tags").Where(a => a.ArticleID == articleID).FirstOrDefault();
                        if (article == null)
                            return false;

                        article.Title = title;
                        article.SubTitle = subTitle;
                        article.ArticleText = text;
                        article.Author = author;
                        article.Photo = photo;
                        article.ModifyDate = DateTime.Now;
                        article.AllowComments = allowComments;

                        var articleTags = article.Tags;
                        article.Tags.Clear();
                        foreach (var tg in tags.Split(','))
                        {
                            var oldtg = context.Tags.Where(t => t.TagName == tg).FirstOrDefault();
                            if (oldtg == null)
                            {
                                var newTag = new Tag() { TagName = tg };
                                article.Tags.Add(newTag);
                            }
                            else
                            {
                                if (!articleTags.Contains(oldtg))
                                {
                                    article.Tags.Add(oldtg);
                                }
                            }
                        }
                        context.SaveChanges();
                    }
                    #endregion

                    #region insert article
                    else    // INSERT
                    {
                        var article = new Article()
                        {
                            Title = title,
                            SubTitle = subTitle,
                            ArticleText = text,
                            Author = author,
                            Photo = photo,
                            CreateDate = DateTime.Now,
                            ModifyDate = null,
                            AllowComments = allowComments
                        };

                        foreach (var tg in tags.Split(','))
                        {
                            var oldtg = context.Tags.Where(t => t.TagName == tg).FirstOrDefault();
                            if (oldtg == null)
                                oldtg = new Tag() { TagName = tg };
                            article.Tags.Add(oldtg);
                        }
                        context.Articles.AddObject(article);
                    }
                    #endregion

                    context.SaveChanges();
                    return true;
                }
            }
            catch
            {
                return false;
            }
        }


        public void Delete(long articleID)
        {
            using (var context = new blogEntities())
            {
                var article = context.Articles.Where(a => a.ArticleID == articleID).FirstOrDefault();
                if (article == null)
                    return;

                context.Articles.DeleteObject(article);
                context.SaveChanges();
            }
        }


        public List<Article> GetArticles(long? articleId, DateTime? startDate)
        {
            using (var context = new blogEntities())
            {
                var articles = context.Articles.Include("Comments").Include("Tags").Where(a =>
                    (a.ArticleID == articleId || articleId == null) &&
                    (a.CreateDate >= startDate || startDate == null)).OrderByDescending(a => a.CreateDate).ThenByDescending(a => a.ModifyDate).ToList();
                return articles;
            }

        }

        public Article GetArticleWithComments(long articleId)
        {
            using (var context = new blogEntities())
            {
                var article = context.Articles.Include("Comments").Include("Tags").Where(a => a.ArticleID == articleId).FirstOrDefault();
                return article;
            }
        }



        public long CommentCreateUpdate(long? commentID, long articleID, string author, string text)
        {
            try
            {
                using (var context = new blogEntities())
                {
                    Comment comment;
                    if (commentID.HasValue)
                    {
                        return -1;
                    }
                    else
                    {
                        comment = new Comment()
                        {
                            Author = author,
                            CommentText = text,
                            CreateDate = DateTime.Now,
                            ArticleID = articleID
                        };
                        context.Comments.AddObject(comment);
                    }
                    context.SaveChanges();
                    return comment.CommentID;
                }
            }
            catch (Exception ex)
            {
                return -1;
            }
        }

        public List<Comment> GetComments(long articleId)
        {
            List<Comment> comments;
            try
            {
                using (var context = new blogEntities())
                {
                    comments = context.Comments.Where(c => c.ArticleID == articleId).ToList();
                }
            }
            catch (Exception ex)
            {
                comments = new List<Comment>();
            }
            return comments;
        }

    }


    #region helper classes ...
    public class TagEqualityComparer : IEqualityComparer<Tag>
    {

        public bool Equals(Tag x, Tag y)
        {
            if (x.TagID == y.TagID || x.TagName == y.TagName)
            {
                return true;
            }
            return false;
        }

        public int GetHashCode(Tag obj)
        {
            return obj.TagName.GetHashCode() + obj.TagID.GetHashCode();
        }
    }

    public class NewsFeedData
    {
        public long? ArticleID { get; set; }
        public long? CommentID { get; set; }
        public string Title { get; set; }
        public string Text { get; set; }
        public string Author { get; set; }
        public DateTime CreateDate { get; set; }
        public NewsType Type { get; set; }

        public enum NewsType
        {
            COMMENT,
            ARTICLE
        }

        public List<NewsFeedData> LoadNews(DateTime fromDate, int maxItems)
        {
            try
            {
                using (var context = new blogEntities())
                {
                    List<NewsFeedData> list = new List<NewsFeedData>();
                    list.AddRange(context.Comments.Include("Article")
                        .OrderByDescending(c => c.CreateDate)
                        .Where(c => c.CreateDate > fromDate)
                        .Select(c => new NewsFeedData()
                        {
                            ArticleID = c.ArticleID,
                            CommentID = c.CommentID,
                            Title = c.Article.Title,
                            Text = c.CommentText,
                            Author = c.Author,
                            CreateDate = c.CreateDate
                        }).AsEnumerable()
                          .Select(c => new NewsFeedData
                          {
                              ArticleID = c.ArticleID,
                              CommentID = c.CommentID,
                              Title = c.Title,
                              Text = c.Text,
                              Author = c.Author,
                              CreateDate = c.CreateDate,
                              Type = NewsType.COMMENT
                          }).ToList());
                    list.AddRange(context.Articles
                        .OrderByDescending(a => a.CreateDate)
                        .Where(a => a.CreateDate > fromDate)
                        .Select(a => new NewsFeedData()
                                {
                                    ArticleID = a.ArticleID,
                                    CommentID = null,
                                    Title = a.Title,
                                    Author = a.Author,
                                    CreateDate = a.CreateDate
                                }).AsEnumerable()
                                  .Select(a => new NewsFeedData
                                  {
                                      ArticleID = a.ArticleID,
                                      CommentID = null,
                                      Title = a.Title,
                                      Author = a.Author,
                                      CreateDate = a.CreateDate,
                                      Type = NewsType.ARTICLE
                                  }).ToList());
                    //IEnumerable<NewsFeedData> list = listOfComments.Union(listOfArticles);
                    return list.Take(maxItems).ToList();
                }
            }
            catch (Exception ex)
            {
                return new List<NewsFeedData>();
            }

        }

        /*
         
         ArticleID ,
         CommentID ,
         Comment AS Text,
         Author ,
         CreateDate,
         'C' AS 'Type'
         
         */
    }
    #endregion helpers
}
